// 封装 axios
import axios from 'axios'
import store from '@/store'
import { message } from 'antd'
// 导入自定义的history对象
import { customHistory } from '@/utils'
import { delLogout } from '@/store/actions'

// 获取环境变量中配置的 url 地址
const baseURL =
  process.env.NODE_ENV === 'development' ? process.env.REACT_APP_URL : '/api'
export const http = axios.create({
  // baseURL: 'http://toutiao.itheima.net/v1_0',
  // baseURL: '/api',
  baseURL,
  timeout: 5000,
})

// 将来可以继续进行拦截器的处理

// 请求拦截器
http.interceptors.request.use((config) => {
  const { login: token } = store.getState()
  // 除了登录请求外，其他请求统一添加 token
  if (!config.url.startsWith('/authorization')) {
    config.headers.Authorization = `Bearer ${token}`
  }
  return config
})

// 响应拦截器
// 因为现在只需要处理 请求失败的情况，所以第一个参数(请求成功的回调)不需要处理
http.interceptors.response.use(undefined, (error) => {
  // 响应失败时，会执行此处的回调函数
  if (!error.response) {
    // 如果没有rsponse说明网络超时了
    message.error('网络繁忙，请稍后再试')
    return Promise.reject(error)
  }

  if (error.response.status === 401) {
    // 说明token失效 就让用户去登录，并重定向去登录页(login)
    message.warning('登录超时，请重新登录', 1, () => {
      // push() 也可以通过第二个参数来指定路由跳转时携带的信息
      customHistory.push('/login', {
        from: customHistory.location.pathname,
      })

      // 触发退出 action 将token等清除
      store.dispatch(delLogout())
    })
  }

  // Promise.reject() 是 Promise 提供的一个快捷方法，可以直接得到一个失败的 Promise 对象
  return Promise.reject(error)
  // 补充：
  // Promise.reject(error)直接得到一个失败的 Promise 对象
  // 相当于：
  // new Promise((resolve, reject) => {
  //   reject(error)
  // })

  // Promise.resolve(data)直接得到一个成功的 Promise 对象
  // 相当于：
  // new Promise((resolve, reject) => {
  //   resolve(data)
  // })

  // 什么情况下使用快捷方法，什么情况使用 new Promise()的方式？
  // 如果直接有 成功的数据 或者失败的错误对象 那么就使用快捷方法(Promise.resolve 或 Promise.reject)
  // 如果是需要经过一些逻辑判断等处理后，才能知道是否发生错误，此时就自己创建一个 Promise 对象，也就是
  // 使用 new Promise() 的形式
})
